﻿using Admin.NET.Application.Entity;

using Admin.NET.Application.Service.DeviceSlaveTemplatePointsValue.Dto;
using Admin.NET.Application.Service.ModbusTcp;
using Admin.NET.Application.Service.ModbusTcpService;
using Admin.NET.Core.Service;
using Microsoft.AspNetCore.Http;
using NewLife;
using NewLife.Net.Modbus1;
using SKIT.FlurlHttpClient.Wechat.Api.Events;
using static Admin.NET.Application.Service.ModbusTcpService.ModbusTcpService;

namespace Admin.NET.Application;

/// <summary>
/// 从机变量服务
/// </summary>
[ApiDescriptionSettings(ApplicationConst.GroupName, Order = 100)]
public class DeviceSlaveTemplatePointsValueService : IDynamicApiController, ITransient
{
    private readonly SqlSugarRepository<DeviceSlaveTemplatePoints> _deviceSlaveTemplatePointsRep;
    private readonly SqlSugarRepository<DevicePointsValue> _devicePointsValueRep;
    private readonly DevicePointsValueService devicePointsValueService;
    private readonly ModbusInfoManager modbusInfoManager;

    public DeviceSlaveTemplatePointsValueService(SqlSugarRepository<DeviceSlaveTemplatePoints> deviceSlaveTemplatePointsRep, SqlSugarRepository<DevicePointsValue> devicePointsValueRep, DevicePointsValueService devicePointsValueService, ModbusInfoManager modbusInfoManager)
    {
        this._devicePointsValueRep = devicePointsValueRep;
        this.devicePointsValueService = devicePointsValueService;
        this.modbusInfoManager = modbusInfoManager;
        _deviceSlaveTemplatePointsRep = deviceSlaveTemplatePointsRep;
    }

    /// <summary>
    /// 分页查询从机变量实时值
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Page")]
    [DisplayName("分页查询从机变量实时值")]
    public async Task<SqlSugarPagedList<DeviceSlaveTemplatePointsOutput>> Page(PageDeviceSlaveTemplatePointsValueInput input)
    {
        //根据deviceid从ServerHandler中获取  todo  null-->DeviceInfo
        var connectDeviceInfo = modbusInfoManager.GetModbusConnectInfoByDeviceId(input.DeviceId.Value);
        var deviceInfo = connectDeviceInfo.Item2;
        ModbusConnectInfo connectInfo = connectDeviceInfo.Item1;
        if (connectInfo != null)
        {
            //根据模板id获取modbusInfo模板下的所有点位

            var slave = deviceInfo.DeviceRelSlaves.FirstOrDefault(u => u.DeviceSlaveTemplateId == input.DeviceSlaveTemplateId);
            if (slave != null)
            {
                var points = slave.DeviceSlaveTemplate.DeviceSlaveTemplatePoint;
                //分页
                return new SqlSugarPagedList<DeviceSlaveTemplatePointsOutput>
                {
                    Total = points.Count,
                    Page = input.Page,
                    PageSize = input.PageSize,
                    Items = points.Skip((input.Page - 1) * input.PageSize).Take(input.PageSize).Select(u => new DeviceSlaveTemplatePointsOutput
                    {
                        Id = u.Id,
                        PointType = u.PointType,
                        PointName = u.PointName,
                        DataIdentifier = u.DataIdentifier,
                        Millennials = u.Millennials,
                        DataType = u.DataType,
                        Len = u.Len,
                        reg = u.reg,
                        RegType = u.RegType,
                        VarType = u.VarType,
                        Unit = u.Unit,
                        ReadWrite = u.ReadWrite,
                        Store = u.Store,
                        Cycle = u.Cycle,
                        CreateTime = u.CreateTime,
                        UpdateTime = u.UpdateTime,
                        CreateUserId = u.CreateUserId,
                        CreateUserName = u.CreateUserName,
                        UpdateUserId = u.UpdateUserId,
                        UpdateUserName = u.UpdateUserName,
                        IsDelete = u.IsDelete,
                        PrecisionEnum = (PrecisionEnum)u.PrecisionEnum,
                        DataValue = u.DataValue
                    }).ToList()
                };
            }
        }

        //modbusInfo=null 直接从数据库中获取DeviceInfo
        var query = _deviceSlaveTemplatePointsRep.AsQueryable()
            .WhereIF(input.DeviceSlaveTemplateId > 0, u => u.DeviceSlaveTemplateId == input.DeviceSlaveTemplateId)
            .Select(u => new DeviceSlaveTemplatePointsOutput
            {
                Id = u.Id,
                PointType = u.PointType,
                PointName = u.PointName,
                DeviceSlaveTemplateId = u.DeviceSlaveTemplateId,
                DataIdentifier = u.DataIdentifier,
                Millennials = u.Millennials,
                DataType = u.DataType,
                Len = u.Len,
                reg = u.reg,
                RegType = u.RegType,
                VarType = u.VarType,
                Unit = u.Unit,
                ReadWrite = u.ReadWrite,
                Store = u.Store,
                Cycle = u.Cycle,
                CreateTime = u.CreateTime,
                UpdateTime = u.UpdateTime,
                CreateUserId = u.CreateUserId,
                CreateUserName = u.CreateUserName,
                UpdateUserId = u.UpdateUserId,
                UpdateUserName = u.UpdateUserName,
                IsDelete = u.IsDelete,
                PrecisionEnum = (PrecisionEnum)u.PrecisionEnum,
            });

        var pageList = (await query.OrderBuilder(input).ToPagedListAsync(input.Page, input.PageSize));
        //遍历pageList.items 从数据库中拉取DevicePointsValue，赋值给DataValue
        //根据DeviceSlaveTemplatePointsId从数据库DevicePointsValue中获取

        var devicePointsValue = _devicePointsValueRep.AsQueryable().Where(u => u.DeviceInfoId == input.DeviceId).ToList();
        foreach (var item in pageList.Items)
        {
            var points = devicePointsValue.FirstOrDefault(u => u.DeviceSlaveTemplatePointsId == item.Id);
            if (points != null)
            {
                item.DataValue = points.PonitValue;
            }
            else
            {
                item.DataValue = "--";
            }
        }

        //返回
        return pageList;
    }

    [HttpPost]
    [ApiDescriptionSettings(Name = "GetDeviceCurrentState")]
    [DisplayName("查询设备变量实时值")]
    public DeviceInfo GetDeviceCurrentState(DeviceSlaveTemplatePointsValueReadInput input)
    {
        return modbusInfoManager.GetModbusConnectInfoByDeviceId(input.DeviceId).Item2;
    }

    /// <summary>
    /// 获取变量值
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "ReadPointValue")]
    [DisplayName("获取变量值")]
    public string ReadPointValue(DeviceSlaveTemplatePointsValueReadInput input)
    {
        //根据deviceid从ServerHandler中获取  todo  null-->DeviceInfo
        var connectDeviceInfo = modbusInfoManager.GetModbusConnectInfoByDeviceId(input.DeviceId);
        var modbusInfo = connectDeviceInfo.Item1;
        if (modbusInfo == null)
        {
            throw Oops.Oh(ErrorCodeEnum.Device003);
        }

        var slave = connectDeviceInfo.Item2.DeviceRelSlaves.FirstOrDefault(u => u.DeviceSlaveTemplateId == input.DeviceSlaveTemplateId);
        if (slave == null)
        {
            throw Oops.Oh(ErrorCodeEnum.Device004);
        }

        var point = slave.DeviceSlaveTemplate.DeviceSlaveTemplatePoint.FirstOrDefault(u => u.Id == input.Id);
        if (point == null)
            throw Oops.Oh(ErrorCodeEnum.Device005);

        var result = modbusInfo.ReadByPoint(point, slave.SlaveAddr);
        var re = modbusInfo.ReadValueToString(result);
        modbusInfoManager.UpdataPointValue(input.DeviceId.Value, point, re, ReadValueType.ManualCollect, point.DataValue);

        return re;
    }

    /// <summary>
    /// 写入变量值
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "WritePointValue")]
    [DisplayName("写入变量值")]
    public string WritePointValue(DeviceSlaveTemplatePointsValueWriteInput input)
    {
        // 根据 deviceId 从 ModbusInfoManager 中获取 ModbusConnectInfo 和 DeviceInfo
        var connectDeviceInfo = modbusInfoManager.GetModbusConnectInfoByDeviceId(input.DeviceId);
        var modbusInfo = connectDeviceInfo.Item1;
        if (modbusInfo == null)
        {
            throw Oops.Oh(ErrorCodeEnum.Device003);
        }

        var slave = connectDeviceInfo.Item2.DeviceRelSlaves.FirstOrDefault(u => u.DeviceSlaveTemplateId == input.DeviceSlaveTemplateId);
        if (slave == null)
        {
            throw Oops.Oh(ErrorCodeEnum.Device004);
        }

        var point = slave.DeviceSlaveTemplate.DeviceSlaveTemplatePoint.FirstOrDefault(u => u.Id == input.Id);
        if (point == null)
        {
            throw Oops.Oh(ErrorCodeEnum.Device005);
        }

        // 将输入的值写入到设备
        var result1 = modbusInfo.WriteByPoint(point, input.DataValue, slave.SlaveAddr);

        var result = modbusInfo.ReadByPoint(point, slave.SlaveAddr);
        var re = modbusInfo.ReadValueToString(result);

        // 更新点位值
        modbusInfoManager.UpdataPointValue(input.DeviceId.Value, point, input.DataValue, ReadValueType.ManualSet, point.DataValue);

        return re;
    }
}